package {{packageName}}.core.{{entity.module}}.service.impl;

{{#if entity.hasBigDecimal}}
import java.math.BigDecimal;
{{/if}}
import java.util.*;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.util.*;
import cn.ibizlab.util.errors.*;
import cn.ibizlab.util.enums.CheckKeyStatus;
{{#system.enableGlobalTransaction}}
import io.seata.spring.annotation.GlobalTransactional;
{{/system.enableGlobalTransaction}}
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.domainClassName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import {{packageName}}.core.{{entity.module}}.service.{{entity.codeName}}Service;
import {{packageName}}.core.{{entity.module}}.mapper.{{entity.codeName}}Mapper;
import {{packageName}}.util.enums.Entities;
{{#if entity.allPSDEWFs}}
import cn.hutool.core.convert.Convert;
import cn.ibizlab.util.enums.FlowEventType;
{{/if}}
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
{{#if entity.isLogicInheritDE}}
import com.baomidou.mybatisplus.core.conditions.Wrapper;
{{/if}}
{{#entity.allRelEntities}}
import {{packageName}}.core.{{module}}.domain.{{domainClassName}};
{{#neq storage "NONE"}}
import {{packageName}}.core.{{module}}.service.{{codeName}}Service;
{{/neq}}
{{/entity.allRelEntities}}

/**
 * 实体[{{entity.logicName}}] 服务对象接口实现
 *
 * @author generator
 */
@Slf4j
public abstract class Abstract{{entity.codeName}}Service extends ServiceImpl<{{entity.codeName}}Mapper,{{entity.domainClassName}}> implements {{entity.codeName}}Service {

    {{#entity.relEntities}}
    {{#neq storage "NONE"}}
    @Autowired
    @Lazy
    protected {{codeName}}Service {{camelCase codeName}}Service;

    {{/neq}}
    {{/entity.relEntities}}
    {{#each entity.references as |reference|}}
        {{#eq reference.entityCodeName entity.codeName}}
    {{#not entity.extParams.checkRefSelf}}{{extParams entity "checkRefSelf" true}}@Autowired
    @Lazy
    protected {{entity.codeName}}Service {{camelCase entity.codeName}}Service;

    {{/not}}
        {{/eq}}
    {{/each}}
    {{#if entity.indexSubDE}}
    @Autowired
    @Lazy
    protected {{packageName}}.core.{{entity.module}}.mapping.{{entity.codeName}}InheritMapping {{camelCase entity.codeName}}InheritMapping;

    {{/if}}
    protected int batchSize = 500;

{{#each entity.sqlImplementMethods}}
    {{#if dataSet}}
   public {{outParam}} fetch{{pascalCase codeName}}({{inParam}} context) {
        {{#if entity.allPSDEWFs}}
        Map<String,Map<String,Object>> businesskeys = fillWFTaskContext(context);
        {{/if}}
        {{#if dataSet.sortInfo}}
        if(context.getPageSort() == null || context.getPageSort() == Sort.unsorted())
            context.setSort("{{dataSet.sortInfo}}");
        {{/if}}
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<{{#if dataSet.enableGroup}}Map{{else}}{{entity.domainClassName}}{{/if}}> pages=baseMapper.search{{pascalCase codeName}}(context.getPages(),context,context.getSelectCond());
        {{#if entity.allPSDEWFs}}
        if(!ObjectUtils.isEmpty(context.getSrfWF()))
            fillWFParam(pages.getRecords(),businesskeys);
        {{/if}}
        {{#if dataSet.enableGroup}}
        return new PageImpl<{{entity.domainClassName}}>(cn.ibizlab.util.helper.JacksonUtils.toArray(pages.getRecords(),{{entity.domainClassName}}.class), context.getPageable(), pages.getTotal());
        {{else}}
        List<{{entity.domainClassName}}> list = pages.getRecords();
            {{#each entity.nesteds as | nest |}}
                    {{!全部数据}}
                    {{#eq viewLevel 0}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .stream().collect(Collectors.groupingBy(e->e.get{{pascalCase nest.fkField.codeName}}())).entrySet().forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.getKey())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub.getValue())));
                    {{/eq}}
                    {{!指定属性组}}
                    {{#eq viewLevel 100}}
                        {{#each pSDEFGroup.pSDEFGroupDetails as |groupDetail|}}
                            {{#eq groupDetail.pSDEField.codeName nest.codeName}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .stream().collect(Collectors.groupingBy(e->e.get{{pascalCase nest.fkField.codeName}}())).entrySet().forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.getKey())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub.getValue())));
                            {{/eq}}
                        {{/each}}
                    {{/eq}}
            {{/each}}
            {{#each entity.nestedObjs as | nest |}}
                    {{!全部数据}}
                    {{#eq viewLevel 0}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.get{{pascalCase nest.fkField.codeName}}())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub)));
                    {{/eq}}
                    {{!指定属性组}}
                    {{#eq viewLevel 100}}
                        {{#each pSDEFGroup.pSDEFGroupDetails as |groupDetail|}}
                            {{#eq groupDetail.pSDEField.codeName nest.codeName}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.get{{pascalCase nest.fkField.codeName}}())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub)));
                            {{/eq}}
                        {{/each}}
                    {{/eq}}
            {{/each}}
        return new PageImpl<>(list, context.getPageable(), pages.getTotal());
        {{/if}}
    }

   public List<{{entity.domainClassName}}> list{{pascalCase codeName}}({{inParam}} context) {
        {{#if dataSet.sortInfo}}
        if(context.getPageSort() == null || context.getPageSort() == Sort.unsorted())
            context.setSort("{{dataSet.sortInfo}}");
        {{/if}}
        {{#if dataSet.enableGroup}}
        return cn.ibizlab.util.helper.JacksonUtils.toArray(baseMapper.list{{pascalCase codeName}}(context,context.getSelectCond()),{{entity.domainClassName}}.class);
        {{else}}
        List<{{entity.domainClassName}}> list = baseMapper.list{{pascalCase codeName}}(context,context.getSelectCond());
        {{#each entity.nesteds as | nest |}}
                    {{!全部数据}}
                    {{#eq viewLevel 0}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .stream().collect(Collectors.groupingBy(e->e.get{{pascalCase nest.fkField.codeName}}())).entrySet().forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.getKey())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub.getValue())));
                    {{/eq}}
                    {{!指定属性组}}
                    {{#eq viewLevel 100}}
                        {{#each pSDEFGroup.pSDEFGroupDetails as |groupDetail|}}
                            {{#eq groupDetail.pSDEField.codeName nest.codeName}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .stream().collect(Collectors.groupingBy(e->e.get{{pascalCase nest.fkField.codeName}}())).entrySet().forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.getKey())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub.getValue())));
                            {{/eq}}
                        {{/each}}
                    {{/eq}}
        {{/each}}
        {{#each entity.nestedObjs as | nest |}}
                    {{!全部数据}}
                    {{#eq viewLevel 0}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.get{{pascalCase nest.fkField.codeName}}())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub)));
                    {{/eq}}
                    {{!指定属性组}}
                    {{#eq viewLevel 100}}
                        {{#each pSDEFGroup.pSDEFGroupDetails as |groupDetail|}}
                            {{#eq groupDetail.pSDEField.codeName nest.codeName}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.get{{pascalCase nest.fkField.codeName}}())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub)));
                            {{/eq}}
                        {{/each}}
                    {{/eq}}
        {{/each}}
        return list;
        {{/if}}
   }
	
    {{else if builtinAction}}
        {{#if (eq codeName 'Get')}}
    public {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et) {
        {{entity.domainClassName}} rt = this.baseMapper.selectEntity(et);
        if(rt == null)
            throw new NotFoundException("数据不存在",Entities.{{entity.definitionName}}.toString(),et.get{{pascalCase entity.keyField.codeName}}());
        rt.copyTo(et,true);
        {{#entity.nesteds}}
        //设置 [{{entityLogicName}}]
        get{{pascalCase codeName}}(et);
        {{/entity.nesteds}}
        {{#entity.nestedObjs}}
        //设置 [{{entityLogicName}}]
        get{{pascalCase codeName}}(et);
        {{/entity.nestedObjs}}
        return et;
    }	

    public List<{{outParam}}> {{camelCase codeName}}(List<{{entity.domainClassName}}> entities) {
        {{#if entity.unionKeyMode}}
        entities.forEach(et->{
            if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
                et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
            });
        {{/if}}
        return this.baseMapper.selectEntities(entities);
    }	
	
        {{else if (eq codeName 'GetDraft')}}
    public {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
        {{#entity.hasReferences}}
        fillParentData({{inParamName}});
        {{/entity.hasReferences}}
        return {{inParamName}};
    }
	
        {{else if (eq codeName 'CheckKey')}}
    public CheckKeyStatus {{camelCase codeName}}({{inParam}} et) {
        {{#entity.hasPhisicalLinkField}}
        fillParentData(et);
        {{/entity.hasPhisicalLinkField}}
        {{#if entity.unionKeyMode}}
        if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
            et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
        {{/if}}
        return (!ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()) && this.count(Wrappers.<{{entity.domainClassName}}>lambdaQuery(){{#each entity.keyFields as |field|}}.eq({{entity.domainClassName}}::get{{pascalCase field.codeName}}, et.get{{pascalCase field.codeName}}()){{/each}})>0)? CheckKeyStatus.FOUNDED : CheckKeyStatus.NOT_FOUND;
    }
	
        {{else if (eq codeName 'Create')}}
    @Override
    {{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}({{inParam}} et) {
        {{#entity.hasReferences}}
        fillParentData(et);
        {{/entity.hasReferences}}
        {{#if entity.isIndexSubDE}}
        {{#neq entity.indexRelation.relEntity.storageMode 0}}
        if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
            et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
        {{entity.indexRelation.entityDomainClassName}} {{camelCase entity.indexRelation.entityCodeName}} = {{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et);
            {{#if entity.indexRelation.indexTypePSDEField}}
        {{camelCase entity.indexRelation.entityCodeName}}.set("{{lowerCase entity.indexRelation.indexTypePSDEField.codeName}}","{{entity.indexRelation.typeValue}}");
            {{/if}}
        {{camelCase entity.indexRelation.entityCodeName}}Service.create({{camelCase entity.indexRelation.entityCodeName}});
        {{else}}
            {{#if entity.unionKeyMode}}
        if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
            et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
            {{/if}}
        {{/neq}}
        {{else}}
            {{#if entity.unionKeyMode}}
        if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
            et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
            {{/if}}
        {{/if}}
        {{#if entity.isLogicInheritDE}}
        if(!update(et, (Wrapper) et.getUpdateWrapper(true).eq("{{lowerCase entity.keyField.name}}", et.get{{pascalCase keyField.codeName}}())))
            return false;
        {{else}}
        {{#neq entity.storageMode 0}}
        if(this.baseMapper.insert(et) < 1)
            return false;
        {{/neq}}
        {{/if}}
        {{#each entity.nesteds}}
        {{camelCase entityCodeName}}Service.saveBy{{pascalCase majorCodeName}}(et,et.get{{pascalCase codeName}}());
        {{/each}}
        {{#each entity.nestedObjs}}
        if(et.get{{pascalCase codeName}}()!=null) {
            et.get{{pascalCase codeName}}().set{{pascalCase fkField.codeName}}(et.get{{pascalCase entity.keyField.codeName}}());
            et.get{{pascalCase codeName}}().set{{pascalCase majorCodeName}}(et);
            {{camelCase entityCodeName}}Service.save(et.get{{pascalCase codeName}}());
        }
        {{/each}}
        get(et);
        {{#if entity.hasPSDERsMapping}}
        updateParentData(et);
        {{/if}}
        return true;
    }
	
    {{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list) {
        {{#if (or entity.actions.create.psDEActionLogics entity.isIndexSubDE)}}
        list.forEach(et->getSelf().create(et));
        {{else}}
            {{#entity.hasReferences}}
        list.forEach(this::fillParentData);
            {{/entity.hasReferences}}
        {{#if entity.unionKeyMode}}
        list.forEach(et->{
            if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
                et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
            });
        {{/if}}
        {{#neq entity.storageMode 0}}
        this.saveBatch(list, batchSize);
        {{/neq}}
            {{#if entity.hasPSDERsMapping}}
        updateParentDataBatch(list);
            {{/if}}
        {{/if}}
        return true;
    }
	
        {{else if (eq codeName 'Update')}}
    {{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}({{inParam}} et) {
        {{#entity.hasPhisicalLinkField}}
        fillParentData(et);
        {{/entity.hasPhisicalLinkField}}
        {{#entity.isIndexSubDE}}
            {{#neq entity.indexRelation.relEntity.storageMode 0}}
        {{entity.indexRelation.entityDomainClassName}} {{camelCase entity.indexRelation.entityCodeName}} = {{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et);
                {{#if entity.indexRelation.indexTypePSDEField}}
        {{camelCase entity.indexRelation.entityCodeName}}.set("{{lowerCase entity.indexRelation.indexTypePSDEField.codeName}}","{{entity.indexRelation.typeValue}}");
                {{/if}}
        {{camelCase entity.indexRelation.entityCodeName}}Service.save({{camelCase entity.indexRelation.entityCodeName}});
            {{/neq}}
        {{/entity.isIndexSubDE}}
        {{#neq entity.storageMode 0}}
        UpdateWrapper<{{entity.domainClassName}}> qw = et.getUpdateWrapper(true);
            {{#each entity.keyFields as |field|}}
        qw.eq("{{lowerCase field.name}}", et.get{{pascalCase field.codeName}}());
            {{/each}}
        if(!update(et, qw))
            return false;
        {{/neq}}
        {{#each entity.nesteds}}
        {{camelCase entityCodeName}}Service.saveBy{{pascalCase majorCodeName}}(et,et.get{{pascalCase codeName}}());
        {{/each}}
        {{#each entity.nestedObjs}}
        if(et.get{{pascalCase codeName}}() != null) {
            et.get{{pascalCase codeName}}().set{{pascalCase fkField.codeName}}(et.get{{pascalCase entity.keyField.codeName}}());
            et.get{{pascalCase codeName}}().set{{pascalCase majorCodeName}}(et);
            {{camelCase entityCodeName}}Service.save(et.get{{pascalCase codeName}}());
        }
        {{/each}}
        get(et);
        {{#if entity.hasPSDERsMapping}}
        updateParentData(et);
        {{/if}}
        return true;
    }

    {{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list) {
        {{#if (or entity.actions.update.psDEActionLogics entity.isIndexSubDE (not entity.keyField.phisicalDEField))}}
        list.forEach(et->getSelf().update(et));
        {{else}}
            {{#entity.hasPhisicalLinkField}}
        list.forEach(this::fillParentData);
            {{/entity.hasPhisicalLinkField}}
            {{#neq entity.storageMode 0}}
        updateBatchById(list, batchSize);
            {{/neq}}
            {{#if entity.hasPSDERsMapping}}
        updateParentDataBatch(list);
            {{/if}}   
        {{/if}}
        return true;
    }
	
        {{else if (eq codeName 'Save')}}
    @Override
    {{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}({{inParam}} et) {
        if(CheckKeyStatus.FOUNDED == checkKey(et))
            return getSelf().update(et);
        else
            return getSelf().create(et);
    }

    {{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list) {
        if(ObjectUtils.isEmpty(list))
            return true;
        Map<{{entity.keyField.type.java}},{{entity.domainClassName}}> before = get(list).stream().collect(Collectors.toMap({{entity.domainClassName}}::get{{pascalCase entity.keyField.codeName}},e->e));
        List<{{entity.domainClassName}}> create = new ArrayList<>();
        List<{{entity.domainClassName}}> update = new ArrayList<>();
        list.forEach(sub->{
            {{#if entity.unionKeyMode}}
            if(ObjectUtils.isEmpty(sub.get{{pascalCase entity.keyField.codeName}}()))
                before.values().stream()
                        .filter(e->ObjectUtils.nullSafeEquals(sub.getDefaultKey(true),e.getDefaultKey(true)))
                        .findFirst().ifPresent(e->sub.set{{pascalCase entity.keyField.codeName}}(e.get{{pascalCase entity.keyField.codeName}}()));
            {{/if}}
            if(!ObjectUtils.isEmpty(sub.get{{pascalCase entity.keyField.codeName}}()) && before.containsKey(sub.get{{pascalCase entity.keyField.codeName}}()))
                update.add(sub);
            else
                create.add(sub);
        });
        if(!update.isEmpty())
            update.forEach(item->this.getSelf().update(item));
        if(!create.isEmpty() && !getSelf().create(create))
            return false;
        else
            return true;
    }
	
        {{else if (eq codeName 'Remove')}}
   {{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et) {
        {{#if entity.hasSubRemoveRelationships}}
        {{entity.keyField.type.java}} key = et.get{{pascalCase entity.keyField.codeName}}();
        {{/if}}
        {{#if entity.hasPSDERsMapping}}
        get(et); 
        {{/if}}
        {{#entity.subRemoveRelationships}}
            {{#eq removeActionType 1}}
        {{camelCase entityCodeName}}Service.removeBy{{pascalCase fkField.codeName}}(key);
            {{/eq}}
            {{#eq removeActionType 2}}
        {{camelCase entityCodeName}}Service.resetBy{{pascalCase fkField.codeName}}(key);
            {{/eq}}
            {{#eq removeActionType 3}}
        if(!ObjectUtils.isEmpty({{camelCase entityCodeName}}Service.findBy{{pascalCase fkField.codeName}}(key)))
            throw new BadRequestAlertException("删除数据失败，当前数据存在关系实体[{{camelCase entityCodeName}}]数据，无法删除!",Entities.{{entity.definitionName}}.toString(),key);
            {{/eq}}
        {{/entity.subRemoveRelationships}}
        {{#entity.isIndexSubDE}}
            {{#neq entity.indexRelation.relEntity.storageMode 0}}
        {{camelCase entity.indexRelation.entityCodeName}}Service.remove({{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et));
            {{/neq}}
        {{/entity.isIndexSubDE}}
        {{#neq entity.storageMode 0}}
        if(!remove(Wrappers.<{{entity.domainClassName}}>lambdaQuery(){{#each entity.keyFields as |field|}}.eq({{entity.domainClassName}}::get{{pascalCase field.codeName}}, et.get{{pascalCase field.codeName}}()){{/each}}))
            return false;
        {{/neq}}
        {{#if entity.hasPSDERsMapping}}
        updateParentData(et);
        {{/if}}
        return true;
    }

    {{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
    public {{outParam}} {{camelCase codeName}}(List<{{entity.domainClassName}}> entities) {
        {{#if (or entity.actions.update.psDEActionLogics entity.isIndexSubDE entity.hasPSDERsMapping entity.hasSubRemoveRelationships)}}
        for ({{entity.domainClassName}} et : entities)
            if(!getSelf().remove(et))
                return false;
        return true;
        {{else}}
        {{#neq entity.storageMode 0}}
        this.baseMapper.deleteEntities(entities);
        {{/neq}}
        return true;
        {{/if}}
    }		
        {{/if}}
    {{else if reference}}
        {{#if (eq type 'find')}}
	public {{outParam}} {{camelCase codeName}}(List<{{inParam}}> {{inParamName}}s){
        List<{{entity.domainClassName}}> list = baseMapper.findBy{{pascalCase fkField.codeName}}({{camelCase fkField.codeName}}s);
        {{#each ownerEntity.nesteds as | nest |}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .stream().collect(Collectors.groupingBy(e->e.get{{pascalCase nest.fkField.codeName}}())).entrySet().forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.getKey())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub.getValue())));
        {{/each}}
        {{#each ownerEntity.nestedObjs as | nest |}}
        if(!ObjectUtils.isEmpty(list))
            {{camelCase nest.entityCodeName}}Service.findBy{{pascalCase nest.fkField.codeName}}(list.stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList()))
                .forEach(sub->list.stream().filter(item->item.get{{pascalCase entity.keyField.codeName}}().equals(sub.get{{pascalCase nest.fkField.codeName}}())).findFirst().ifPresent(item->item.set{{pascalCase nest.codeName}}(sub)));
        {{/each}}
        return list;	
	}

        {{else if (eq type 'findByCode')}}
	public {{outParam}} {{camelCase codeName}}({{inBody}}){
            {{#if parentSubType}}
                {{#if emptyParentSubTypeValue}}
        List<{{entity.domainClassName}}> list = this.baseMapper.selectList(Wrappers.<{{entity.domainClassName}}>lambdaQuery()
                        .eq({{entity.domainClassName}}::get{{pascalCase fkField.codeName}}, {{camelCase entityCodeName}}.get{{pascalCase relField.codeName}}())
                        .eq({{entity.domainClassName}}::get{{pascalCase parentTypeField.codeName}},"{{relation.relEntity.name}}").isNull({{entity.domainClassName}}::get{{pascalCase parentSubTypeField.codeName}}));
                {{else}}
        List<{{entity.domainClassName}}> list = this.baseMapper.selectList(Wrappers.<{{entity.domainClassName}}>lambdaQuery()
                        .eq({{entity.domainClassName}}::get{{pascalCase fkField.codeName}}, {{camelCase entityCodeName}}.get{{pascalCase relField.codeName}}())
                        .eq({{entity.domainClassName}}::get{{pascalCase parentTypeField.codeName}},"{{relation.relEntity.name}}")
                        .eq({{entity.domainClassName}}::get{{pascalCase parentSubTypeField.codeName}},"{{relation.typeValue}}"));
                {{/if}}
            {{else}}
        List<{{entity.domainClassName}}> list = findBy{{pascalCase fkField.codeName}}(Arrays.asList({{camelCase entityCodeName}}.get{{pascalCase relField.codeName}}()));
            {{/if}}
		return list;
	}
        {{else if (eq type 'remove')}}
	public {{outParam}} {{camelCase codeName}}({{inBody}}){
        {{#if (or entity.actions.update.psDEActionLogics entity.isIndexSubDE entity.hasPSDERsMapping entity.hasSubRemoveRelationships)}}
        List<{{entity.keyField.type.java}}> ids = baseMapper.findBy{{pascalCase fkField.codeName}}(Arrays.asList({{camelCase fkField.codeName}})).stream().map(e->e.get{{pascalCase entity.keyField.codeName}}()).collect(Collectors.toList());
        if(!ObjectUtils.isEmpty(ids))
            return this.remove(ids);
        else
            return true;
        {{else}}
        return this.remove(Wrappers.<{{entity.domainClassName}}>lambdaQuery().eq({{entity.domainClassName}}::get{{pascalCase fkField.codeName}},{{camelCase fkField.codeName}}));
        {{/if}}	
	}

        {{else if (eq type 'reset')}}
	public {{outParam}} {{camelCase codeName}}({{inBody}}){
		return this.update(Wrappers.<{{entity.domainClassName}}>lambdaUpdate().set({{entity.domainClassName}}::get{{pascalCase fkField.codeName}}, null).eq({{entity.domainClassName}}::get{{pascalCase fkField.codeName}},{{camelCase fkField.codeName}}));
	}
        {{else if (eq type 'saveByCode')}}
	public {{outParam}} {{camelCase codeName}}({{inBody}}){
        if(list==null)
            return true;

        Map<{{entity.keyField.type.java}},{{entity.domainClassName}}> before = findBy{{pascalCase relation.codeName}}({{camelCase entityCodeName}}).stream().collect(Collectors.toMap({{entity.domainClassName}}::get{{pascalCase entity.keyField.codeName}},e->e));
        List<{{entity.domainClassName}}> update = new ArrayList<>();
        List<{{entity.domainClassName}}> create = new ArrayList<>();

        for({{entity.domainClassName}} sub:list) {
            sub.set{{pascalCase fkField.codeName}}({{camelCase entityCodeName}}.get{{pascalCase relField.codeName}}());
            sub.set{{pascalCase relation.codeName}}({{camelCase entityCodeName}});
            {{#if entity.unionKeyMode}}
            if(ObjectUtils.isEmpty(sub.get{{pascalCase entity.keyField.codeName}}()))
                before.values().stream()
                        .filter(e->ObjectUtils.nullSafeEquals(sub.getDefaultKey(true),e.getDefaultKey(true)))
                        .findFirst().ifPresent(e->sub.set{{pascalCase entity.keyField.codeName}}(e.get{{pascalCase entity.keyField.codeName}}()));
            {{/if}}
            if(!ObjectUtils.isEmpty(sub.get{{pascalCase entity.keyField.codeName}}())&&before.containsKey(sub.get{{pascalCase entity.keyField.codeName}}())) {
                before.remove(sub.get{{pascalCase entity.keyField.codeName}}());
                update.add(sub);
            }
            else
                create.add(sub);
        }
        if(!update.isEmpty())
            update.forEach(item->this.getSelf().update(item));
        if(!create.isEmpty() && !getSelf().create(create))
            return false;
        else if(!before.isEmpty() && !getSelf().remove(before.keySet()))
            return false;
        else
            return true;
			
	}
        {{/if}}
	{{else if nested}}
	@Override
    public {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et) {
        List<{{entityDomainClassName}}> list = {{camelCase entityCodeName}}Service.findBy{{pascalCase relation.opt.codeName}}(et);
        et.set{{pascalCase relation.codeName}}(list);
        return list;
    }
	
	{{else if nestedObj}}
    @Override
    public {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et) {
        {{camelCase entityCodeName}}Service.findBy{{pascalCase fkField.codeName}}(et.get{{pascalCase entity.keyField.codeName}}()).stream().findFirst().ifPresent(->et.set{{pascalCase codeName}}(e));
        return et.get{{pascalCase relation.codeName}}();
    }
	
    {{/if}}
{{/each}}

    {{#entity.hasReferences}}
    public void fillParentData({{entity.domainClassName}} et) {
        {{#each entity.references as |reference|}}
            {{#neq entityStorage "NONE"}}
        if(Entities.{{reference.relEntity.definitionName}}.equals(et.getContextParentEntity()) && et.getContextParentKey()!=null) {
            et.set{{pascalCase reference.fkField.codeName}}(({{reference.fkField.javaType}})et.getContextParentKey());
            {{#gt reference.relFieldCount 1}}
                {{#lte reference.relPhisicalFieldCount 1}}
            {{reference.entityDomainClassName}} {{camelCase reference.entityCodeName}} = et.get{{pascalCase reference.codeName}}();
            if({{camelCase reference.entityCodeName}} == null) {
                {{camelCase reference.entityCodeName}} = {{camelCase reference.entityCodeName}}Service.getById(et.get{{pascalCase reference.fkField.codeName}}());
                et.set{{pascalCase reference.codeName}}({{camelCase reference.entityCodeName}});
            }
            if(!ObjectUtils.isEmpty({{camelCase reference.entityCodeName}})) {
                {{#each reference.fields as |field|}}
                et.set{{pascalCase field.codeName}}({{camelCase reference.entityCodeName}}.get{{pascalCase field.refFieldCodeName}}());
                {{/each}}
            }
                {{/lte}}
            {{/gt}}
        }
        {{#gt reference.relPhisicalFieldCount 1}}
        if(!ObjectUtils.isEmpty(et.get{{pascalCase reference.fkField.codeName}}())) {
            {{reference.entityDomainClassName}} {{camelCase reference.entityCodeName}} = et.get{{pascalCase reference.codeName}}();
            if({{camelCase reference.entityCodeName}} == null) {
                {{camelCase reference.entityCodeName}} = {{camelCase reference.entityCodeName}}Service.getById(et.get{{pascalCase reference.fkField.codeName}}());
                et.set{{pascalCase reference.codeName}}({{camelCase reference.entityCodeName}});
            }
            if(!ObjectUtils.isEmpty({{camelCase reference.entityCodeName}})) {
                {{#each reference.fields as |field|}}
                et.set{{pascalCase field.codeName}}({{camelCase reference.entityCodeName}}.get{{pascalCase field.refFieldCodeName}}());
                {{/each}}
            }
        }
        {{/gt}}
        {{/neq}}
        {{/each}}
    }

    {{/entity.hasReferences}}
	{{#if entity.allPSDEWFs}}
    @Autowired
    protected cn.ibizlab.util.client.FlowFeignClient flowFeignClient;

    /**
     * 查询统一工作流待办
     * @param context
     */
    protected Map<String,Map<String,Object>> fillWFTaskContext({{entity.codeName}}SearchContext context){
        Map<String, Map<String, Object>> businessKeys = null;
        if(!ObjectUtils.isEmpty(context.getSrfWF())){
            businessKeys = flowFeignClient.toDoKeys("{{system.deploySysId}}","{{entity.opt.codeName}}",context.getProcessDefinitionKey(),context.getUserTaskId(),null);
            if(!ObjectUtils.isEmpty(businessKeys)) {
                context.getSelectCond().in("{{entity.keyField.columnName}}", {{#eq entity.keyField.type.java "Long"}}Convert.toLongArray(businessKeys.keySet()){{else}}businessKeys.keySet(){{/eq}});
            }
            else {
                context.getSelectCond().apply("1<>1");
            }
        }
        return businessKeys;
    }

    /**
     * 填充工作流参数
     * @param data
     * @param businessKeys
     */
    protected void fillWFParam(List data, Map<String, Map<String, Object>> businessKeys) {
        if (!ObjectUtils.isEmpty(data) && !ObjectUtils.isEmpty(businessKeys)) {
            data.forEach(entity->{
                if (entity instanceof {{entity.domainClassName}}){
                    Object id = (({{entity.domainClassName}}) entity).get{{pascalCase entity.keyField.codeName}}();
                    if (!ObjectUtils.isEmpty(id) && businessKeys.containsKey(id.toString())) {
                        businessKeys.get(id.toString()).entrySet().forEach(entry -> {
                            (({{entity.domainClassName}}) entity).set(entry.getKey(), entry.getValue());
                        });
                    }
                }
                else if(entity instanceof Map){
                    Object id = ((Map) entity).get("{{lowerCase entity.keyField.codeName}}");
                    if (!ObjectUtils.isEmpty(id) && businessKeys.containsKey(id.toString())) {
                        businessKeys.get(id.toString()).entrySet().forEach(entry -> {
                            ((Map<String, Object>) entity).put(entry.getKey(), entry.getValue());
                        });
                    }
                }
            });
        }
    }

    @Override
    public boolean onFlowEvent(String eventType, {{entity.domainClassName}} et) {
        switch (FlowEventType.valueOf(eventType.toUpperCase())) {
            case PROCESS_STARTED:
                this.getSelf().update(et);
                break;
            case ACTIVITY_STARTED:
                this.getSelf().update(et);
                break;
            case PROCESS_COMPLETED:
                this.getSelf().update(et);
                break;
            case TASK_COMPLETED:
                break;
        }
        return true;
    }

    {{/if}}
    {{#if entity.hasPSDERsMapping}}
    /**
    * 更新父数据（实体关系属性映射）
    * @param et
    */
    protected void updateParentData({{entity.domainClassName}} et){
    }

    protected void updateParentDataBatch(List <{{entity.domainClassName}}> entities){
    }

    {{/if}}

    @Override
    @Transactional
    public boolean execute(String sql , Map param){
        if (sql == null || sql.isEmpty()) {
            return false;
        }
        if (sql.toLowerCase().trim().startsWith(SqlMethod.INSERT_ONE.getMethod())) {
            return this.baseMapper.insertBySQL(sql,param);
        }
        if (sql.toLowerCase().trim().startsWith(SqlMethod.UPDATE.getMethod())) {
            return this.baseMapper.updateBySQL(sql,param);
        }
        if (sql.toLowerCase().trim().startsWith(SqlMethod.DELETE.getMethod())) {
            return this.baseMapper.deleteBySQL(sql,param);
        }
        log.warn("暂未支持的SQL语法");
        return true;
    }
	
	@Override
    protected Class currentMapperClass() {
        return {{entity.codeName}}Mapper.class;
    }

    @Override
    protected Class currentModelClass() {
        return {{entity.domainClassName}}.class;
    }

}